package com.cfweb.api;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.cfweb.controller.LoginHandler;
import com.cfweb.util.CloudFoundryClientUtil;
import com.cfweb.util.JsonUtil;

public class DomainApi {
	
	static Logger logger = Logger.getLogger(OrgApi.class);
	
	/**
     * get domains in the org
     * @param orgName
     * @param session
     * @return List<Map<String, Object>>
     * @throws Exception 
     */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> get_domains_for_org(HttpSession session, String orgName) throws Exception {
		
		String orgId;
		orgId = UserApi.get_org_id(session, orgName);
		List<Map<String, Object>> res = new ArrayList<Map<String, Object>>();
		if (orgId.isEmpty()) {
			return null;
		}
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/organizations/" + orgId + "/domains?results-per-page=100";
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			Map<String, Object> data = JsonUtil.convertJsonToMap(content);
			List<Map<String, Object>> lr = (List<Map<String, Object>>)data.get("resources");
			String next_url=(String) data.get("next_url");
			while(next_url!=null){
				next_url=ApiCommonUtil.retriveAllPageResource(lr,next_url,session);
			}
			for (Map<String, Object> r : lr){
				Map<String,Object> tmp = new HashMap<String,Object>();
				Map<String, Object> entity = (Map<String, Object>)r.get("entity");
				String name = (String)entity.get("name");
				tmp.put("name", name);
				if (entity.containsKey("owning_organization_guid")) {
					String orgGuid = (String) entity.get("owning_organization_guid");
					tmp.put("status", "owned");
					tmp.put("org_guid", orgGuid);
				} else {
					tmp.put("status", "shared");
				}
				res.add(tmp);
			}
		} catch (Exception e) {
			throw e;
		}
		return res;
	}
	
	/**
     * create private domain in the org
     * @param orgName
     * @param session
     * @param domainName
     * @return boolean
     * @throws Exception 
     */
	public static boolean create_private_domain_for_org(HttpSession session, String orgName, String domainName) throws Exception {
		String orgId;
		orgId = UserApi.get_org_id(session, orgName);
		if (orgId.isEmpty()) {
			return false;
		}
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/private_domains?async=true";
			Map<String, Object> params = new HashMap<String,Object>();
			params.put("name", domainName);
			params.put("owning_organization_guid", orgId);
			params.put("wildcard", "true");
			String content = CloudFoundryClientUtil.doCCPost(urlPath, params, session);
		} catch (Exception e) {
			throw e;
		}
		return true;
	}
	
	/**
     * delete private domain in the org
     * @param orgName
     * @param session
     * @param domainName
     * @return boolean
     * @throws Exception 
     */
	public static boolean delete_private_domain_for_org(HttpSession session, String orgName, 
			String domainName) throws Exception{
		String domainId = get_domain_id(session, orgName, domainName);
		if (domainId.isEmpty()) {
			return false;
		}
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/private_domains/" + domainId + "?async=false&recursive=true";
			String content = CloudFoundryClientUtil.doCCDelete(urlPath, null, session);
		} catch (Exception e) {
			throw e;
		}
		return true;
	}
	
	/**
     * create shared domain
     * @param session
     * @param domainName
     * @return boolean
     * @throws Exception 
     */
	public static boolean create_shared_domain(HttpSession session, String domainName) throws Exception{
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/shared_domains?async=true";
			Map<String, Object> params = new HashMap<String,Object>();
			params.put("name", domainName);
			params.put("wildcard", "true");
			String content = CloudFoundryClientUtil.doCCPost(urlPath, params, session);
		} catch (Exception e) {
			throw e;
		}
		return true;
	}
	
	/**
     * delete shared domain
     * @param session
     * @param domainName
     * @return boolean
     * @throws Exception 
     */
	public static boolean delete_shared_domain(HttpSession session, String domainName) throws Exception{
		String domainId = get_domain_id(session, (String)session.getAttribute(LoginHandler.ORG), domainName);
		if (domainId.isEmpty()) {
			return false;
		}
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/shared_domains/" + domainId + "?async=false&recursive=true";
			String content = CloudFoundryClientUtil.doCCDelete(urlPath, null, session);
		} catch (Exception e) {
			throw e;
		} 
		return true;
	}
	
	/**
     * remove domain
     * @param session
     * @param domainName
     * @param orgName
     * @return boolean
     * @throws Exception 
     */
	public static boolean remove_domain(HttpSession session, String orgName, 
			String domainName) throws Exception {
		if (orgName==null) {
			orgName = (String)session.getAttribute(LoginHandler.ORG);
		}
		String domainId = get_domain_id(session, orgName, domainName);
		if (domainId.isEmpty()) {
			return false;
		}
		try {
			String host = ((URL)session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/domains/" + domainId + "?async=false&recursive=true";
			String content = CloudFoundryClientUtil.doCCDelete(urlPath, null, session);
		} catch (Exception e) {
			throw e;
		}
		return true;
	}
	
	/**
     * get id of domain
     * @param session
     * @param domainName
     * @param orgName
     * @return domainId
     * @throws Exception 
     */
	@SuppressWarnings("unchecked")
	public static String get_domain_id(HttpSession session, String orgName, String domainName) throws Exception {
		String orgId;
		String domainId;
		orgId = UserApi.get_org_id(session, orgName);
		if (orgId.isEmpty()) {
			return "";
		}
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/organizations/" + orgId 
					+ "/domains?inline-relations-depth=1&q=name%3A" + domainName;
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);

			Map<String, Object> data = JsonUtil.convertJsonToMap(content);
			domainId = (String)((Map<String, Object>)((Map<String, Object>)((List)data.get("resources")).get(0)).get("metadata")).get("guid");
		} catch (Exception e) {
			throw e;
		}
		return domainId;
	}
	
	/**
     * check a private domain who is existed or not
     * @param session
     * @param domainName
     * @return boolean
     * @throws Exception 
     */
	public static boolean isPrivateDomainExist(HttpSession session,String domainName) throws Exception {
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/private_domains?q=name:" + domainName;	
			
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			Map<String, Object> data = JsonUtil.convertJsonToMap(content);
			if((int) data.get("total_results") > 0) {
				return true;
			}
			return false;
		} catch (Exception e) {
			throw e;
		}
	}
	
	/**
     * check a shared domain who is existed or not
     * @param session
     * @param domainName
     * @return boolean
     * @throws Exception 
     */
	public static boolean isShareDomainExist(HttpSession session,String domainName) throws Exception {
		try {
			String host = ((URL) session.getAttribute(LoginHandler.TARGET)).toString();
			String urlPath = host + "/v2/shared_domains?q=name:" + domainName;
			String content = CloudFoundryClientUtil.doCCGet(urlPath, null, session);
			Map<String, Object> data = JsonUtil.convertJsonToMap(content);
			if((int) data.get("total_results") > 0) {
				return true;
			}
			return false;
		} catch (Exception e) {
			throw e;
		}
	}
	
	/**
     * get private domains in the org
     * @param session
     * @param orgGuid
     * @return List<Map<String, Object>>
     * @throws Exception 
     */
	public static List<Map<String, Object>> getPrivateDomainOrgs(String orgGuid, HttpSession session) throws Exception {
		String host = ((URL)session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/organizations/"+orgGuid+"/private_domains";
		String content=CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		@SuppressWarnings("unchecked")
		List<Map<String, Object>> domains = (List<Map<String, Object>>)data.get("resources");
		String next_url=(String) data.get("next_url");
		while(next_url!=null){
			next_url=ApiCommonUtil.retriveAllPageResource(domains,next_url,session);
		}
		return domains;
	}
	
	/**
     * get shared domains
     * @param session
     * @return List<Map<String, Object>>
     * @throws Exception 
     */
	@SuppressWarnings("unchecked")
	public static List<Map<String, Object>> getSharedDomain(HttpSession session) throws Exception{
		String host = ((URL)session.getAttribute(LoginHandler.TARGET)).toString();
		String urlPath = host + "/v2/shared_domains";
		String content=CloudFoundryClientUtil.doCCGet(urlPath, null, session);
		Map<String, Object> data = JsonUtil.convertJsonToMap(content);
		List<Map<String, Object>> domains = (List<Map<String, Object>>)data.get("resources");
		String next_url=(String) data.get("next_url");
		while(next_url!=null){
			next_url=ApiCommonUtil.retriveAllPageResource(domains,next_url,session);
		}
		return domains;
	}
	
	/**
     * get guids of domains in the org
     * @param session
     * @param orgGuid
     * @return List<Map<String, Object>>
     * @throws Exception 
     */
	@SuppressWarnings("unchecked")
	public static  Map<String, String> getDomainGuids(String orgGuid,HttpSession session) throws Exception {
		List<Map<String, Object>> privateDomains=getPrivateDomainOrgs(orgGuid, session);
		List<Map<String, Object>> sharedDomains=getSharedDomain(session);
		Map<String, String> domains = new HashMap<String, String>(privateDomains.size() + privateDomains.size());
		for (Map<String, Object> d : privateDomains) {
			domains.put(
					(String)((Map<String, Object>)d.get("entity")).get("name"),
					(String)((Map<String, Object>)d.get("metadata")).get("guid"));
		}
		for (Map<String, Object> d : sharedDomains) {
			domains.put(
					(String)((Map<String, Object>)d.get("entity")).get("name"),
					(String)((Map<String, Object>)d.get("metadata")).get("guid"));
		}
		return domains;
	}

}
